#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <db.h>
#include "amessage.pb-c.h"

int main (int argc, const char * argv[]) 
{
    AMessage msg = AMESSAGE__INIT; // AMessage
    uint8_t *buf;                     // Buffer to store serialized data
    unsigned len;                  // Length of serialized data

    DB *dbp;              /* DB structure handle */
    DBT key, value;
    unsigned int flags;   /* database open flags */
    int ret;              /* function return value */
    int inputKey;

    if (argc != 3 && argc != 4) {
        fprintf(stderr,"Usage: writer key a [b]\n");
        exit(1);
    }

    inputKey = atoi(argv[1]);
    msg.a = atoi(argv[2]);
    if (argc == 4) { 
        msg.has_b = 1; 
        msg.b = atoi(argv[3]); 
    }
    len = amessage__get_packed_size(&msg);

    buf = (uint8_t *)malloc(len);
    fprintf(stdout, "Input message: key: %d, a: %d, b: %d\n", inputKey, msg.a, msg.b);
    amessage__pack(&msg, buf);

    /* Initialize db structure. */
    ret = db_create(&dbp, NULL, 0);
    if (ret != 0) {
        fprintf(stderr, "Error initializing DB\n", len);
        free(buf);
        exit(1);
    }

    /* DB open flags */
    flags = DB_CREATE;

    /* open DB */
    ret = dbp->open(dbp, NULL, "./my.db", NULL, DB_HASH, flags, 0);
    if (ret != 0) {
        fprintf(stderr, "dbp->open: %s\n", db_strerror(ret));
        free(buf);
        if (dbp != NULL) {
            dbp->close(dbp, 0);
        }
        exit(1);
    }

    memset(&key, 0, sizeof(DBT));
    memset(&value, 0, sizeof(DBT));

    key.data = (uint8_t *)&inputKey;
    key.size = sizeof(int);

    value.data = (uint8_t *)buf;
    value.size = len; 

    fprintf(stdout, "Writing %d serialized bytes\n", len);
    fprintf(stdout, "[INFO]\tkey.data: %d\n", *((int *)(key.data))); 
    fprintf(stdout, "[INFO]\tkey.size: %lu\n", sizeof(int)); 
    fprintf(stdout, "[INFO]\tvalue.size: %d\n", value.size); 

    ret = dbp->put(dbp, NULL, &key, &value, 0);
    if (ret != 0) {
        fprintf(stderr, "Error putting ...\n");
        free(buf);
        if (dbp != NULL) {
            dbp->close(dbp, 0);
        }
        exit(1);
    }

    dbp->sync(dbp, 0);
    /* close DB */
    if (dbp != NULL)
        dbp->close(dbp, 0);
    free(buf); // Free the allocated serialized buffer

    return 0;
}

///:~

